#!/usr/bin/env python3
"""
树莓派5 GPIO诊断脚本
"""
import os
import subprocess
import sys

def run_cmd(cmd, shell=False):
    """运行命令"""
    try:
        if shell:
            result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
        else:
            result = subprocess.run(cmd, capture_output=True, text=True)
        return result.returncode == 0, result.stdout, result.stderr
    except Exception as e:
        return False, "", str(e)

def check_rpi5_info():
    """检查树莓派5信息"""
    print("🍓 树莓派5系统检查...")
    
    # 内核版本
    success, stdout, stderr = run_cmd(['uname', '-a'])
    if success:
        print(f"📍 内核: {stdout.strip()}")
    
    # 设备型号
    success, stdout, stderr = run_cmd(['cat', '/proc/device-tree/model'])
    if success:
        print(f"📍 型号: {stdout.strip()}")
    
    # 检查RP1芯片（树莓派5的IO芯片）
    success, stdout, stderr = run_cmd(['lspci | grep -i rp1'], shell=True)
    if success and stdout:
        print(f"📍 RP1芯片: {stdout.strip()}")
    else:
        print("📍 RP1芯片: 未找到（可能正常）")

def check_rpi5_gpio_drivers():
    """检查树莓派5 GPIO驱动"""
    print("\n🔌 检查树莓派5 GPIO驱动...")
    
    # 树莓派5使用RP1芯片，驱动不同
    rpi5_drivers = [
        'pinctrl_rp1',
        'gpio_rp1',
        'raspberrypi_gpio'
    ]
    
    print("检查已加载模块:")
    success, stdout, stderr = run_cmd(['lsmod'], shell=True)
    if success:
        found_drivers = []
        for driver in rpi5_drivers:
            if driver in stdout:
                found_drivers.append(driver)
                print(f"✅ {driver}: 已加载")
        
        if not found_drivers:
            print("❌ 未找到树莓派5 GPIO驱动")
            
            # 尝试加载
            print("\n尝试加载驱动...")
            for driver in rpi5_drivers:
                success, stdout, stderr = run_cmd(['sudo', 'modprobe', driver])
                if success:
                    print(f"✅ 成功加载: {driver}")
                else:
                    print(f"❌ 加载失败: {driver}")

def check_rpi5_gpio_chips():
    """检查树莓派5 GPIO芯片"""
    print("\n📋 检查GPIO芯片...")
    
    # 树莓派5有多个GPIO芯片
    gpio_base = '/sys/class/gpio'
    if os.path.exists(gpio_base):
        chips = [f for f in os.listdir(gpio_base) if f.startswith('gpiochip')]
        if chips:
            print("找到GPIO芯片:")
            for chip in sorted(chips):
                chip_path = os.path.join(gpio_base, chip)
                try:
                    with open(os.path.join(chip_path, 'label'), 'r') as f:
                        label = f.read().strip()
                    with open(os.path.join(chip_path, 'base'), 'r') as f:
                        base = f.read().strip()
                    with open(os.path.join(chip_path, 'ngpio'), 'r') as f:
                        ngpio = f.read().strip()
                    print(f"  🎯 {chip}: {label} (GPIO {base}-{int(base)+int(ngpio)-1})")
                except Exception as e:
                    print(f"  ❌ {chip}: 无法读取信息")
        else:
            print("❌ 未找到GPIO芯片")

def check_libgpiod():
    """检查libgpiod（树莓派5推荐）"""
    print("\n📚 检查libgpiod...")
    
    # libgpiod是树莓派5推荐的GPIO访问方式
    try:
        import gpiod
        print("✅ gpiod Python库可用")
        
        # 尝试列出芯片
        chips = list(gpiod.chip_iter())
        if chips:
            print("找到GPIO芯片:")
            for chip in chips:
                print(f"  🎯 {chip.name()}: {chip.label()} ({chip.num_lines()} lines)")
        else:
            print("❌ 未找到GPIO芯片")
            
    except ImportError:
        print("❌ gpiod Python库不可用")

def test_rpi5_gpio_access():
    """测试树莓派5 GPIO访问"""
    print("\n🧪 测试GPIO访问...")
    
    # 方法1: 尝试libgpiod
    print("方法1: 使用libgpiod")
    try:
        import gpiod
        chip = gpiod.chip('gpiochip0')
        line = chip.get_line(17)  # GPIO17
        
        # 配置为输出
        config = gpiod.line_request()
        config.consumer = "rpi5-test"
        config.request_type = gpiod.line_request.DIRECTION_OUTPUT
        
        line.request(config)
        line.set_value(1)
        print("✅ libgpiod: 设置GPIO17为高电平")
        line.set_value(0)
        print("✅ libgpiod: 设置GPIO17为低电平")
        line.release()
        print("🎉 libgpiod访问成功！")
        return True
        
    except Exception as e:
        print(f"❌ libgpiod失败: {e}")
    
    # 方法2: 尝试RPi.GPIO（可能不支持树莓派5）
    print("\n方法2: 使用RPi.GPIO")
    try:
        import RPi.GPIO as GPIO
        GPIO.setmode(GPIO.BCM)
        GPIO.setwarnings(False)
        
        # 测试输入模式
        GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
        value = GPIO.input(17)
        print(f"✅ RPi.GPIO: 读取GPIO17 = {value}")
        
        GPIO.cleanup()
        print("🎉 RPi.GPIO访问成功！")
        return True
        
    except Exception as e:
        print(f"❌ RPi.GPIO失败: {e}")
    
    return False

def install_libgpiod():
    """安装libgpiod"""
    print("\n📥 安装libgpiod...")
    
    commands = [
        "sudo apt update",
        "sudo apt install -y gpiod libgpiod-dev python3-libgpiod"
    ]
    
    for cmd in commands:
        print(f"执行: {cmd}")
        success, stdout, stderr = run_cmd(cmd, shell=True)
        if success:
            print("✅ 成功")
        else:
            print(f"❌ 失败: {stderr}")

def main():
    print("=" * 70)
    print("               树莓派5 GPIO诊断工具")
    print("=" * 70)
    
    check_rpi5_info()
    check_rpi5_gpio_drivers()
    check_rpi5_gpio_chips()
    check_libgpiod()
    
    gpio_working = test_rpi5_gpio_access()
    
    if not gpio_working:
        print("\n🚨 GPIO访问失败，建议安装libgpiod...")
        choice = input("是否安装libgpiod? (y/N): ")
        if choice.lower() == 'y':
            install_libgpiod()
            print("\n🔄 安装完成，重新测试...")
            gpio_working = test_rpi5_gpio_access()
    
    print("\n" + "=" * 70)
    if gpio_working:
        print("🎉 树莓派5 GPIO访问正常！")
        print("💡 建议使用libgpiod进行开发")
    else:
        print("❌ GPIO访问失败")
        print("建议:")
        print("1. 更新系统: sudo apt update && sudo apt upgrade")
        print("2. 安装libgpiod")
        print("3. 检查硬件连接")
    print("=" * 70)

if __name__ == '__main__':
    main()